/* =============================================================
 * port_picker.js v1.1.0
 * =============================================================
 * Original written by Ysy
 * =============================================================
 * Date 03/06/2020
 * ============================================================ */

(function (factory) {
    "use strict";
    if (typeof define === 'function' && define.amd) {
        define(['jquery'], factory);
    } else {
        factory(jQuery);
    }
}(function ($) {

    let CityPicker = function (element, options) {
        this.options = $.extend({}, $.fn.cityPicker.defaults, options);
        this.source = this.options.source;
        this.$element = $(element);
        this.$container = $(this.options.container);
        this.$tab = $(this.options.tab);
        this.$main = $(this.options.main);
        this.$remark = $(this.options.remark);

        this.afterSelect = this.options.afterSelect;
        this.afterHide = this.options.afterHide;

        this.tab = "";// 1：省  2：市  3：区  4：镇  5：街道
        this.isNextLevel = true; // 是否有下一等级
        this.list = [];
        this.provinceList = [];
        this.cityList = [];
        this.areaList = [];
        this.townList = [];
        this.streetList = [];
        this.province = {};
        this.city = {};
        this.area = {};
        this.town = {};
        this.street = {};
        this.code = "";
        this.name = "";
        this.shown = false;

        if (Object.is(1,this.options.loading)) {
            this.off();
        }

        this.listen();
    };

    CityPicker.prototype = {

        constructor: CityPicker,

        render: function () {// 渲染
            this.$container.append(this.$tab);// 标题
            this.$container.append(this.$main);// 主题
            this.$container.append(this.$remark);// 备注信息

            // 初始化有默认值  数据回显
            let initCode = this.options.initCode;
            let initName = this.options.initName;

            if (this.isEmptyString(this.tab) && Object.keys(initCode).length !== 0 && Object.keys(initName).length !== 0) {
                let codeArr = initCode.split("-");
                $.each(codeArr, (index, value) => {
                    switch (index) {
                        case 0:
                            this.province.code = value;
                            break;
                        case 1:
                            this.city.code = value;
                            break;
                        case 2:
                            this.area.code = value;
                            break;
                        case 3:
                            this.town.code = value;
                            break;
                        case 4:
                            this.street.code = value;
                            break;
                    }
                });
                let nameArr = initName.split("/");
                $.each(nameArr, (index, value) => {
                    switch (index) {
                        case 0:
                            this.province.name = value;
                            break;
                        case 1:
                            this.city.name = value;
                            break;
                        case 2:
                            this.area.name = value;
                            break;
                        case 3:
                            this.town.name = value;
                            break;
                        case 4:
                            this.street.name = value;
                            break;
                    }
                });
            }

            let tab = "";
            $.each(this.options.tabContent, (index, value) => {
                // tab 数据回显
                if (Object.is(0, index) && Object.keys(this.province).length !== 0) {
                    tab += "<li data-id='" + (index + 1) + "' data-code='" + this.province.code + "' class='active'>" + "." + this.province.name + "</li>";
                } else if (Object.is(1, index) && Object.keys(this.city).length !== 0) {
                    tab += "<li data-id='" + (index + 1) + "' data-code='" + this.city.code + "' class='active'>" + "." + this.city.name + "</li>";
                } else if (Object.is(2, index) && Object.keys(this.area).length !== 0) {
                    tab += "<li data-id='" + (index + 1) + "' data-code='" + this.area.code + "' class='active'>" + "." + this.area.name + "</li>";
                } else if (Object.is(3, index) && Object.keys(this.town).length !== 0) {
                    tab += "<li data-id='" + (index + 1) + "' data-code='" + this.town.code + "' class='active'>" + "." + this.town.name + "</li>";
                } else if (Object.is(4, index) && Object.keys(this.street).length !== 0) {
                    tab += "<li data-id='" + (index + 1) + "' data-code='" + this.street.code + "' class='active'>" + "." + this.street.name + "</li>";
                } else {
                    tab += "<li data-id='" + (index + 1) + "' data-code=''>" + value + "</li>";
                }
            });
            this.$tab.find("ul").html(tab);
            this.tab = this.tab || 1;
            this.$tab.find("ul li").eq(this.tab - 1).addClass("selected");

            this.$remark.find("span").text(this.options.remarkContent);
            $(this.$element).after(this.$container);

            if ($.isFunction(this.source)) {
                this.source($.proxy(this.process, this));
            } else if (this.source) {
                this.list = this.source;
                this.displayText();
            }

            this.show();
        },

        flexSet: function () {
            // flex 布局 填满元素
            let num = this.$main.find("ul li").length % 6;
            for (let i = 0; i < 6 - num; i++) {
                this.$main.find("ul").append("<li class='disabled'></li>");
            }
        },

        displayText: function () {
            let html = "";

            switch (this.tab) {
                case 1:
                    $.each(this.list, (index, value) => {
                        if (this.province.code == value.code) {
                            html += "<li class='selected' data-code='" + value.code + "'>" + value.name + "</li>";
                        } else {
                            html += "<li data-code='" + value.code + "'>" + value.name + "</li>";
                        }
                        this.provinceList.push(value);
                    });
                    break;
                case 2:
                    let province = this.provinceList.find((x) => {
                        return x.code == this.province.code;
                    });
                    $.each(province.areaList, (index, value) => {
                        if (this.city.code == value.code) {
                            html += "<li class='selected' data-code='" + value.code + "'>" + value.name + "</li>";
                        } else {
                            html += "<li data-code='" + value.code + "'>" + value.name + "</li>";
                        }
                        this.cityList.push(value);
                    });
                    break;
                case 3:
                    let city = this.cityList.find((x) => {
                        return x.code == this.city.code;
                    });
                    $.each(city.areaList, (index, value) => {
                        if (this.area.code == value.code) {
                            html += "<li class='selected' data-code='" + value.code + "'>" + value.name + "</li>";
                        } else {
                            html += "<li data-code='" + value.code + "'>" + value.name + "</li>";
                        }
                        this.areaList.push(value);
                    });
                    break;
                case 4:
                    let area = this.areaList.find((x) => {
                        return x.code == this.area.code;
                    });
                    $.each(area.areaList, (index, value) => {
                        if (this.town.code == value.code) {
                            html += "<li class='selected' data-code='" + value.code + "'>" + value.name + "</li>";
                        } else {
                            html += "<li data-code='" + value.code + "'>" + value.name + "</li>";
                        }
                        this.townList.push(value);
                    });
                    break;
                case 5:
                    let town = this.townList.find((x) => {
                        return x.code == this.town.code;
                    });
                    $.each(town.areaList, (index, value) => {
                        if (this.street.code == value.code) {
                            html += "<li class='selected' data-code='" + value.code + "'>" + value.name + "</li>";
                        } else {
                            html += "<li data-code='" + value.code + "'>" + value.name + "</li>";
                        }
                        this.streetList.push(value);
                    });
                    break;
            }

            this.$main.find("ul").html(html);

            this.isEmptyString(html) ? this.isNextLevel = false : this.isNextLevel = true;

            this.isNextLevel && this.flexSet();
        },

        init: function (e) {
            e.stopPropagation();
            e.preventDefault();
            this.render();
        },

        off: function () {// 解绑事件
            this.$element.off("click blur");

            this.$main.off("click", "ul li");

            this.$tab.off("click", "ul li");
        },

        listen: function () {
            this.$element
                .on("click", $.proxy(this.init, this))
                .on("blur", $.proxy(this.blur, this));

            this.$main
                .on("click", "ul li", $.proxy(this.select, this));

            this.$tab
                .on("click", "ul li", $.proxy(this.tabSwitch, this));

            // 全局点击空白处隐藏事件
            $(document).on("click", (e) => {
                let event = e.target || e.srcElement;
                let boolean = true;
                while (event) { // 循环判断至跟节点，防止点击的是div子元素
                    if ($(event).hasClass("city_picker_container")) {
                        boolean = false;
                        return;
                    }
                    event = event.parentNode;
                }

                boolean && this.shown && this.hide();
            });
        },

        tabSwitch: function (e) {
            let tab = $(e.target).data("id");
            switch (tab) {
                case 1:
                    break;
                case 2:
                    if (this.isEmptyString(this.province.code)) return false;
                    break;
                case 3:
                    if (this.isEmptyString(this.city.code)) return false;
                    break;
                case 4:
                    if (this.isEmptyString(this.area.code)) return false;
                    break;
                case 5:
                    if (this.isEmptyString(this.town.code)) return false;
                    break;
            }

            this.tab = tab;
            this.tabShow();
            this.displayText();
        },

        select: function (e) {
            e.stopPropagation();
            e.preventDefault();

            if ($(e.target).hasClass("selected")) return false;
            let object = {
                code: $(e.target).data("code"),
                name: $(e.target).text(),
            };
            this.refreshTab(object);

            // 跳到下一级事件处理
            this.tab++;
            this.displayText();
            // 判断没有下一级元素  直接关闭隐藏
            if (!this.isNextLevel) {
                this.tab--;
                this.hide();
            } else {
                this.tabShow();
                this.tab === 6 && this.hide();
            }

            // this.code = (Object.keys(this.province).length === 0 ? "" : this.province.code) + (Object.keys(this.city).length === 0 ? "" : "-" + this.city.code) +
            //     (Object.keys(this.area).length === 0 ? "" : "-" + this.area.code) + (Object.keys(this.town).length === 0 ? "" : "-" + this.town.code) +
            //     (Object.keys(this.street).length === 0 ? "" : "-" + this.street.code);
            // this.name = (Object.keys(this.province).length === 0 ? "" : this.province.name) + (Object.keys(this.city).length === 0 ? "" : "/" + this.city.name) +
            //     (Object.keys(this.area).length === 0 ? "" : "/" + this.area.name) + (Object.keys(this.town).length === 0 ? "" : "/" + this.town.name) +
            //     (Object.keys(this.street).length === 0 ? "" : "/" + this.street.name);

            this.afterSelect(this.province, this.city, this.area, this.town, this.street);
        },

        getNextTabTextAndClear: function (i) {
            let tabText = "";

            switch (i) {
                case 1:
                    tabText = this.options.tabContent[1];
                    this.city = {};
                    break;
                case 2:
                    tabText = this.options.tabContent[2];
                    this.area = {};
                    break;
                case 3:
                    tabText = this.options.tabContent[3];
                    this.town = {};
                    break;
                case 4:
                    tabText = this.options.tabContent[4];
                    this.street = {};
                    break;
                case 5:
                    break;
            }

            return tabText;
        },

        clearTab: function () {
            for (let i = this.tab; i < 5; i++) {
                let code = this.$tab.find("ul li").eq(i).data("code");
                if (!this.isEmptyString(code)) {
                    this.$tab.find("ul li").eq(i).text(this.getNextTabTextAndClear(i));
                    this.$tab.find("ul li").eq(i).data("code", "");
                    this.$tab.find("ul li").eq(i).removeClass("active selected");
                }
            }
        },

        refreshTab: function (object) {
            // 清空之后的tab
            this.clearTab();

            switch (this.tab) {
                case 1:
                    this.$tab.find("ul li").eq(this.tab - 1).text(". " + object.name);
                    this.$tab.find("ul li").eq(this.tab - 1).data("code", object.code);
                    this.province = object;
                    break;
                case 2:
                    this.$tab.find("ul li").eq(this.tab - 1).text(". " + object.name);
                    this.$tab.find("ul li").eq(this.tab - 1).data("code", object.code);
                    this.city = object;
                    break;
                case 3:
                    this.$tab.find("ul li").eq(this.tab - 1).text(". " + object.name);
                    this.$tab.find("ul li").eq(this.tab - 1).data("code", object.code);
                    this.area = object;
                    break;
                case 4:
                    this.$tab.find("ul li").eq(this.tab - 1).text(". " + object.name);
                    this.$tab.find("ul li").eq(this.tab - 1).data("code", object.code);
                    this.town = object;
                    break;
                case 5:
                    this.$tab.find("ul li").eq(this.tab - 1).text(". " + object.name);
                    this.$tab.find("ul li").eq(this.tab - 1).data("code", object.code);
                    this.street = object;
                    break;
            }
            this.$tab.find("ul li").eq(this.tab - 1).addClass("active");
        },

        tabShow: function () {
            this.$tab.find("ul li").removeClass("selected");
            this.$tab.find("ul li").eq(this.tab - 1).addClass("selected");
        },

        // 字符串非空判定
        isEmptyString: function (str) {
            let boolean = true;

            // 正则表达式用于判斷字符串是否全部由空格或换行符组成
            let reg = /^\s*$/;
            if (str && str !== undefined && str != null && str !== "" && !reg.test(str)) boolean = false;

            return boolean;
        },

        show: function () {
            this.shown = true;
            this.hideOther();
            this.$container.fadeIn(200);
        },

        blur: function () {
            this.$container.fadeIn(200);
        },

        hideOther: function () {
            // $("body").find("div.port_picker_container").fadeOut(300);
            // $("body").find("div.addr_history_container ").fadeOut(300);
            // $("body").find("div.city_picker_container").fadeOut(300);
        },

        hide: function () {
            this.shown = false;
            this.$container.fadeOut(200);
            // this.afterHide();
            this.destroy();
        },

        process: function (data) {
            this.list = data;
            this.displayText();
        },

        destroy: function () {
            this.$container.detach();
        },
    };

    let old = $.fn.cityPicker;

    $.fn.cityPicker = function (options) {
        return new CityPicker(this, options);
    };

    $.fn.cityPicker.defaults = {
        container: "<div class='city_picker_container'></div>",
        tab: "<div class='tab'>" +
            "       <ul></ul>" +
            "     </div>",
        main: "<div class='main'>" +
            "           <ul></ul>" +
            "       </div>",
        remark: "<div class='remark'>" +
            "            <p>友情提示：</p>" +
            "            <span></span>" +
            "        </div>",
        tabContent: ["省份", "城市", "区/县名", "镇名", "街道"],
        remarkContent: "请再次确认您的门点选择与实际装货地点一致，如果由于您的门点选择错误，而导致操作异常，致使门服务无法正常完成，所产生的额外费用和相关责任将由您来承担。",
        afterSelect: $.noop(),
        afterHide: $.noop(),
        initCode: "",
        initName: "",
    };

    $.fn.cityPicker.Constructor = CityPicker;

    $.fn.cityPicker.noConflict = function () {
        $.fn.cityPicker = old;
        return this;
    };
}));
